=Product key=
==attributes==

{| cellpadding="5" border="1" cellspacing="0" align="center"  style="text-align: center"
!align="center" style="background-color: #00ff00;"|Name 
!align="center" style="background-color: #00ff00;"|Offset
!align="center" style="background-color: #00ff00;"|Size (bytes)
!align="center" style="background-color: #00ff00;"|Contents
|- 
|versions
|0
|1
|0x00 注册码版本
|-
|server id
|1
|4
|0x04,0x03,0x02,0x01  表示服务器ID0x01020304: 
|- 
|terminal count
|5
|4
|0x00,0x02,0x01,0x00 表示许可终端数0x00010200
|- 
|user count
|9
|2
|0xe8,0x03 表示许可用户数0x03e8
|-
|server model
|11
|1
|服务器型号，默认为0x00
|-
|forever key
|12
|1
|0x00：系统为试用 0x01：为永久注册
|-
|start date
|13
|4
|(大头格式，同serverid)有效起始日期：单位为天，为相对基数20100101以来的时间差
|-
|alidate days
|17
|4
|(大头格式，同serverid)试用天数，试用期为有效
|}

== 注册流程 ==
# 我们针对上面的Product key使用了加密算法，生成的结果是：'''25长度的数字'''
# 注册过程：
    1、服务器提供唯一ID （server id），一般根据硬盘等硬件得到 （已经内置get_serverid_by_dev_serial函数得到）
    2、将server id转换为20长度的数字（调用server_id_viewformat函数），此数字为客户所看到的‘序列号’ （也调用get_serverid_digits_by_dev_serial直接可得到序列号）
    3、客户提供‘序列号’给ITC售后服务人员
    4、售后人员将‘序列号’、注册日期、许可终端数、等注册信息，生成‘注册码’提供给客户注册用
    5、客户输入‘注册码’后，服务器解析得到注册信息（调用product_key_parse函数）
    6、服务器等依据注册信息去实现（限制）功能
# 格式要求：
    序列号20长度数字显示时分为4段：如12345-12345-12345-12345
    注册码25长度数字显示时分为5段：如12345-12345-12345-12345-12345
    中间用分隔符'''-'''或其它分隔，方便用户操作
# 加密算法：

== 验证要求 ==
# 需要防止用户修改服务器时间来延长使用时间，（如每日时间复位到某个时间或之前时间）
# 需要防止用户把时间设置到注册码中的开始时间之前，然后注册来延长使用时间 （强制用户调整为正确的日期）
# 需要防止同一注册码在同一台机器上被激活多次，在多次激活中间修改时间
# 需要验证注册码是为这台主机定制的 （判断server id是否为本机硬盘序列号等得到，注册码versions当前版本为0）
# 需要严格按照注册码里面定义的终端数量来进行限制
# 需要严格的按照注册码里定义的用户数进行限制，注意：这里面的用户数不包括管理员
# 激活需要绑定硬件，如果clone硬盘，不能使用
# 按照最后一次激活的key的相关配置激活主机

=生成器=
生成器目前继续由余工负责，按照之前的样子做进一步升级。
=服务器=
相关要求：
# 可以保存所有注册码历史 
# 可以显示临时注册过的次数
# 完成前面提到的验证要求
==页面==
# 如果服务器处于未激活状态，只显示注册码输入框
# 正常情况下，在主机配置页面可以让用户输入新的注册码来更新用户主机配置，同时这个页面显示一些注册信息